# coding=utf-8
from django.db.models.query_utils import Q
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from trp.models import *
from utils.JsonResponse import *
from django.shortcuts import render_to_response
import datetime
from django.core.exceptions import ObjectDoesNotExist
import json
from django.http.response import HttpResponse
from utils.decorators import *
import time
from django.db.models import Min,Max,Sum 
from website.settings import LOGGER as logger
from trp.views.costlog import get_cost_by_media
from django.db import transaction
from django.template.defaultfilters import floatformat
from utils.utils import date_range_array
@login_required
def main(request):
    account = request.user.account
    if account.is_admin():
        return media_response(request,'trp/media.html',{})    
    else:
        return JsonResponseBadrequest({"message":str("权限不足")})
    

def media_response(request,html,dic):
    return render_to_response(html, dict({'user' : request.user, 'page' : 'media'},**dic))

@login_required_ajax
def get_list(request):
    try:
        account = request.user.account
        if not account.is_admin():
            raise Exception("权限不足")
        params = json.loads(request.body)
        search_text = params.get("searchText", "")  # 模糊搜索
        start = params.get("start")
        end = params.get("end")
        type=params.get("type")
        pageSize = int(params.get("pageSize", 30))
        pageNo = int(params.get("pageNo", 1))
        args = []
        kwargs = {}
        order = []
        if start:
            kwargs["start__gte"] = start
            kwargs["end__lte"] = end
        if type:
            kwargs["type"]=int(type)
        kwargs['deleted'] = False
        if search_text:
            args.append(Q(name__icontains=search_text) | Q(attrs__name__icontains=search_text));
        list = Media.objects.prefetch_related('attrs').filter(*args, **kwargs).order_by("-id").distinct()
        paginator = Paginator(list, pageSize)
        try:
            pageObj = paginator.page(pageNo)
        except PageNotAnInteger:
            pageObj = paginator.page(1)
        except EmptyPage:
            pageObj = paginator.page(paginator.num_pages)
        result = {}
        datalist = media_to_json(pageObj.object_list)
        result['bodyData'] = datalist
        result["pageNo"] = pageNo
        result["pageSize"] = pageSize
        result["totalCount"] = paginator.count
    except Exception,e:
        logger.exception(e)
        return JsonResponseBadrequest({'message':str(e)}) 
    return JsonResponse(result)    

@login_required_ajax
def get(request):
    try:
        account = request.user.account
        if not account.is_admin():
            raise Exception("权限不足")
        if request.method == "POST":
            params = request.POST
        else:
            params = request.GET
        id=int(params.get("id",-1))
        result={}
        obj=Media.objects.get(pk=id)
        datalist=mediaAttrs_to_str(obj.attrs.all())
        result["name"]=obj.name
        result["type"]=obj.type
        result["data"]=datalist
    except Exception,e:
        logger.exception(e)
        return JsonResponseBadrequest({'message':str(e)}) 
    return JsonResponse(result)

@login_required_ajax
def get_attrs(request):
    objs=MediaAttr.objects.all().order_by("-id")
    result={}
    datalist=mediaAttrs_to_str(objs)
    result["data"]=datalist
    return JsonResponse(result)

@login_required_ajax
@transaction.commit_manually
def create(request):
    result={}
    try:
        account = request.user.account
        if not account.is_admin():
            raise Exception("权限不足")
        data=json.loads(request.body)
        name = data["media_name"]
        attrIds = data["media_attrs"]
        type=int(data.get("type",0))
        now = datetime.datetime.now()
        obj = Media.objects.create(name=name, last_update=now, deleted=False,type=type)
        details="名称:"+name.encode("utf-8")+";"
        if type==0:
            details+="媒体类型:站内;"
        elif type==1:
            details+="媒体类型:站外;"
        else:
            details+="媒体类型:联盟;"   
        attr_str=""    
        for id in attrIds:
            attr = MediaAttr.objects.get(id=id)
            obj.attrs.add(attr)
            attr_str+=attr.name.encode("utf-8")+","    
        if attrIds:
            count=len(attr_str)
            attr_str=attr_str[:count-1]
            attr_str="媒体属性:"+attr_str
            details+=attr_str
        operation_log=OperationLog()
        operation_log.operation="新建"
        operation_log.object="媒体"
        operation_log.user=request.user
        operation_log.details=details      
        operation_log.object_id=obj.id 
        operation_log.save()
    except Exception,e:
        transaction.rollback()
        logger.exception(e)
        return JsonResponseBadrequest({'message':str(e)})
    else:
        transaction.commit()       
    return JsonResponse(result)
    
@login_required_ajax
@transaction.commit_manually
def delete(request):
    result={}
    try:
        account = request.user.account
        if not account.is_admin():
            raise Exception("权限不足")
        if request.method == "POST":
            params = request.POST
        else:
            params = request.GET
        media_id = params.get("media_id")
        obj=Media.objects.get(pk=media_id)
        
        now = datetime.datetime.now()
        obj.deleted=True
        obj.last_update=now
        obj.save()
        obj.attrs.clear()
            
        operation_log=OperationLog()
        operation_log.operation="删除"
        operation_log.object="媒体"
        operation_log.user=request.user      
        operation_log.object_id=obj.id 
        operation_log.save()
    except Exception,e:
        transaction.rollback()
        logger.exception(e)
        return JsonResponseBadrequest({'message':str(e)})
    else:
        transaction.commit()      
    return JsonResponse(result)

@login_required_ajax
@transaction.commit_manually
def update(request):
    result={}
    try:
        account = request.user.account
        if not account.is_admin():
            raise Exception("权限不足")
        params = json.loads(request.body)
        media_id = int(params.get("media_id"))
        media_name = params.get("media_name").encode("utf-8")
        attrs_ids = params.get("media_attrs")
        type=int(params.get("type",0))
        now = datetime.datetime.now()
        
        obj = Media.objects.get(pk=media_id)
        old_name=obj.name.encode("utf-8")
        old_type=obj.type
        old_attrs_ids=[]        
        old_attrs=obj.attrs.all()
        for old_attr in old_attrs:
            old_attrs_ids.append(old_attr.id)                  
        obj.name = media_name
        obj.type=type
        obj.last_update = now
        obj.save()
        obj.attrs.clear()
        
        attr_str=""  
        media_attrs_ids=[]
        for media_attrs_id in attrs_ids:
            attr = MediaAttr.objects.get(pk=int(media_attrs_id))
            obj.attrs.add(attr)
            attr_str+=attr.name.encode("utf-8")+"," 
            media_attrs_ids.append(int(media_attrs_id))
        
        operation_log=OperationLog()
        details=""
        if  cmp(old_name,media_name):
            details+="名称:"+media_name+";"
        if old_type!=type:
            if type==0:
                details+="媒体类型:站内;"
            elif type==1:
                details+="媒体类型:站外;"
            else:
                details+="媒体类型:联盟;"   
        old_set=set(old_attrs_ids)
        new_set=set(media_attrs_ids)
        if old_set!= new_set:
            count=len(attr_str)
            attr_str=attr_str[:count-1]
            attr_str="媒体属性:"+attr_str
            details+=attr_str       
        operation_log.operation="修改"
        operation_log.object="媒体"
        operation_log.user=request.user
        operation_log.details=details      
        operation_log.object_id=media_id 
        operation_log.save()
    except Exception,e:
        transaction.rollback()
        logger.exception(e)
        return JsonResponseBadrequest({'message':str(e)})
    else:
        transaction.commit()    
    return JsonResponse(result)

@login_required_ajax
def report(request):
    if request.method == "POST":
        params = request.POST
    else:
        params = request.GET
    media_id = int(params.get("media_id"))
    org= request.user.account.get_organization()    
    start = params.get("start")
    end = params.get("end")

    results = {}
    account = request.user.account
    if not account.is_admin():        
        return JsonResponse(results)           
    medialist=mediaAttrs_to_str(Media.objects.filter(deleted=False)) 
    datalist = media_report_to_str(media_id,start,end)    
    results["data"] = datalist
    results["media"]=medialist  
    return JsonResponse(results)




#***************************************************basic function****************************************************

@login_required_ajax
def get_media_list(request):
    result={}
    objs=Media.objects.filter(deleted=False)
    fields=[]
    fields.append("id")
    fields.append("name")
    fields.append("type")
    result["data"]=get_FieldsValue(objs,fields)
    return JsonResponse(result)

def get_FieldsValue(objs,fields):
    datalist=[]
    for obj in objs:
        data={}
        for field in fields:
            data[field]=getattr(obj,field)
        datalist.append(data)
    return datalist
            

def mediaIsExist(media_name):
    exists = True
    try:
        Media.objects.get(name=media_name)
    except Media.DoesNotExist:
        exists = False
    return exists

def mediaAttrs_to_str(objs):
    datalist=[]
    for obj in  objs:
        data={}
        data["id"]=obj.id
        data["name"]=obj.name
        datalist.append(data)
    return datalist

def media_attrs_to_str(attrs):
    p_attrs = ""
    for attr in attrs:
        if p_attrs == "":
            p_attrs = attr.name
        else:
            p_attrs += "," + attr.name
    return p_attrs

def media_to_json(list):
    datalist = []
    for media in list:
        data = {}
        data["id"] = media.id
        data["media_name"] = media.name
        data["type"]=media.type
        data['media_attrs'] = media_attrs_to_str(media.attrs.all())
        data["can_deleted"]=1
        if media.position_set.filter(deleted=False).exists():
            data["can_deleted"]=0
        datalist.append(data)
    return datalist

def media_report_to_str(media_id,start,end):
    start = datetime.datetime.strptime(start,"%Y-%m-%d").date()
    end = datetime.datetime.strptime(end,"%Y-%m-%d").date()
    datalist = []
    objs=DailyMediaReport.objects.filter(media_id=media_id,date__range=(start, end)).order_by("date").values_list("date","pv","uv","click","cost")
    dateArr = date_range_array(start,end)
    media_data_by_date ={}
    for pd in objs :
        d,pv,uv,click,cost=pd
        media_data_by_date[d]=(pv,uv,click,cost) 
    for d in dateArr :
        pv,uv,click,income = media_data_by_date.get(d,(0,0,0,0))
        data = {}
        data["pv"] = pv
        data["uv"] = uv
        data["click"] = click
        data["ctr"]=0       
        if pv !=0:
            data["ctr"] = floatformat(click / float(pv),arg=-5)
        data["date"] = d.strftime("%Y-%m-%d")        
        data["cost"]=floatformat(get_media_cost(media_id,d),arg=-2)
        data["sale_income"]=floatformat(get_cost_by_media(d,media_id),arg=-2)
        data["bid"]=floatformat(income,arg=-2)
        data["profit"]=floatformat(float(data["bid"])+float(data["sale_income"])-float(data["cost"]),arg=-2)
        datalist.append(data)        
    return datalist

def get_media_cost(id,date):
    media=Media.objects.get(pk=id)
    positions=media.position_set.all()
    cpd=0
    cpm=0
    for position in positions: 
        objs=position.traffic_set.filter(bid_type=0,start__lte=date,end__gte=date,deleted=False)
        if objs.count()>0:
            bid_price=objs[0].bid_price
            cpd+=bid_price
        else:
            objs=DailyPositionReport.objects.filter(position=position,date=date)
            if objs.count()>0:
                pv=objs[0].pv
                try:
                    obj=position.traffic_set.get(bid_type=1,start__lte=date,end__gte=date,deleted=False)
                    bid_price=obj.bid_price
                    cpm+=(pv*bid_price)/float(1000)
                except:
                    pass        
    sum=cpd+cpm
    return sum

def get_media_cpd_cost(id,date):
    media=Media.objects.get(pk=id)
    positions=media.position_set.all()
    sum=0
    for position in positions:
        price=position.traffic_set.filter(bid_type=0,start__lte=date,end__gt=date).aggregate(Sum('bid_price'))
        sum+=price      
    return sum

def get_media_cpm_cost(id,date):
    media=Media.objects.get(pk=id)
    positions=media.position_set.all()
    sum=0
    for position in positions:
        try:
            positionReport=DailyPositionReport.objects.get(position=position,date=date)
            pv=positionReport.pv
            traffic=position.traffic_set.get(bid_type=1,start__lte=date,end__gt=date)
            bid_price=traffic.bid_price
            price=pv*bid_price
            sum+=price
        except ObjectDoesNotExist:
            continue
    return sum


#****************************MediaAttr*******************#
@login_required_ajax
def create_attr(request):
    account = request.user.account
    result={}    
    if account.is_admin():
        if request.method == "POST":
            params = request.POST
        else:
            params = request.GET
        name=params.get("name") 
        try:
            MediaAttr.objects.get(name=name)
            return JsonResponseBadrequest(result)
        except ObjectDoesNotExist:               
            obj=MediaAttr(name=name)
            obj.save()           
            result["id"]=obj.id 
            return JsonResponse(result)

@login_required_ajax
def check_attr(request):
    result={}
    result["tag"]=0
    if request.method == "POST":
        params = request.POST
    else:
        params = request.GET
    id = params.get("id")
    obj=MediaAttr.objects.get(pk=id)
    if obj.media_set.all().exists():
        result["tag"]=1
    return JsonResponse(result)

@login_required_ajax
def delete_attr(request):
    account = request.user.account    
    result={}        
    if account.is_admin():
        if request.method == "POST":
            params = request.POST
        else:
            params = request.GET
        try:
            id = params.get("id")
            obj=MediaAttr.objects.get(pk=id)            
            #obj.media_set.all().clear()
            obj.delete()            
        except Exception,e :
            logger.exception(e)
            return JsonResponseBadrequest({"message":str(e)})
    return JsonResponse({"message":"ok"})
    













